package hbasecli.controller;

import hbasecli.exception.ConvertException;
import hbasecli.exception.DaoException;
import hbasecli.resp.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

@Slf4j
@RestControllerAdvice(basePackages = {"hbasecli.controller"})
public class GlobalExceptionHandler {

    /**
     * 处理HTTP请求格式错误引起的异常
     *
     * @param exception 被处理的异常
     * @return 响应体
     */
    @ResponseStatus(code = HttpStatus.OK)
    @ExceptionHandler(value = {MethodArgumentTypeMismatchException.class, HttpMessageNotReadableException.class})
    public Resp<String> handleHttpException(Exception exception) {
        String detail;
        if (exception instanceof MethodArgumentTypeMismatchException) {
            detail = "URL路径参数类型不匹配";
        } else if (exception instanceof HttpMessageNotReadableException) {
            detail = "请求体中的数据格式不匹配";
        } else {
            detail = "其它请求错误";
        }
        log.error(exception.getMessage());
        return Resp.of(400, "请求格式错误", detail);
    }

    /**
     * 处理数据转换失败的异常
     *
     * @param exception 被处理的异常
     * @return 响应体
     */
    @ResponseStatus(code = HttpStatus.OK)
    @ExceptionHandler(value = {ConvertException.class})
    public Resp<String> handleConvertException(ConvertException exception) {
        log.error(exception.getMsg());
        return Resp.of(501, exception.getMsg(), "");
    }

    /**
     * 处理数据访问操作失败的异常
     *
     * @param exception 被处理的异常
     * @return 响应体
     */
    @ResponseStatus(code = HttpStatus.OK)
    @ExceptionHandler(value = {DaoException.class})
    public Resp<String> handleDaoException(DaoException exception) {
        log.error(exception.getMsg());
        return Resp.of(501, exception.getMsg(), "");
    }

    /**
     * 处理其它的运行时异常
     *
     * @param exception 被处理的异常
     * @return 响应体
     */
    @ResponseStatus(code = HttpStatus.OK)
    @ExceptionHandler(value = {RuntimeException.class})
    public Resp<String> handleRuntimeException(RuntimeException exception) {
        exception.printStackTrace();
        log.error(exception.getMessage());
        return Resp.of(500, exception.getMessage(), "");
    }
}
